<template>
    <div class="todo-container">
        <div class="todo-wrap">
            <Header :add="add" :todos="todos" />
            <List :change="change" :remove="remove" :todos="todos" />
            <Footer :allChange="allChange" :clear="clear" :isBlock="isBlock" :todos="todos" />
        </div>
    </div>
</template>

<script>
import Header from '@/components/Header'
import List from '@/components/List'
import Footer from '@/components/Footer'
import { nanoid } from 'nanoid'

export default {
    name: 'App',
    components: { Header, List, Footer },
    data() {
        return {
            todos: JSON.parse(window.localStorage.getItem('todos') || '[]')
        }
    },
    methods: {
        // 添加任务
        add(e) {
            // 1. 获取用户输入的内容
            const content = e.target.value.trim()
            // 2. 校验合法性
            if (!content.length) {
                return alert('请输入任务名称')
            }
            // 3. 准备一个任务对象
            const todoObj = { id: nanoid(), title: content, done: false }
            // 4. 将任务对象添加到todos中
            this.todos.unshift(todoObj)
            // 5. 清空输入框
            e.target.value = ''
        },
        // 删除单个任务
        remove(id) {
            this.todos = this.todos.filter((todo) => todo.id !== id)
        },
        // 批量更改任务状态
        change(id) {
            this.todos = this.todos.map((todo) => {
                if (todo.id === id) {
                    todo.done = !todo.done
                }
                return todo
            })
        },
        // 全选
        allChange(e) {
            this.todos.forEach((todo) => {
                todo.done = e.target.checked
                return todo
            })
        },
        // 清除已完成任务
        clear() {
            this.todos = this.todos.filter((todo) => !todo.done)
        }
    },
    // 监听todos
    watch: {
        todos: {
            handler() {
                // 将数据存储到本地
                window.localStorage.setItem('todos', JSON.stringify(this.todos))
            },
            // 深度监听
            deep: true
        }
    }
}
</script>

<style scoped></style>
